package controller;

/*Date : Feb/15/2012
 * The controller is used as the first reception for 
 * all the Http requests.
 * 
 * */

import helper.UserType;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import controller.Action;
import model.Model;
import javax.servlet.*;
import javax.servlet.http.*;

import org.mybeans.form.FormBeanException;

import databeans.User;

//The main controller, when the project first run, it goes into controller.
public class Controller extends HttpServlet {

    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public void init() throws ServletException {
        Model model = new Model(getServletConfig());
        // user operation action
        Action.add(new AdminAction(model));
        Action.add(new BinaryqAction(model));
        Action.add(new ChangePasswordAction(model));
        Action.add(new ContinuousqAction(model));
        Action.add(new CreateSurveyAction(model));
        Action.add(new DeleteUserAction(model));
        Action.add(new ImportEntityAction(model));
        Action.add(new LikertqAction(model));
        Action.add(new LoginAction(model));
        Action.add(new LogoutAction(model));
        Action.add(new MailingListAction(model));
        Action.add(new MultipleChoiceqAction(model));
        Action.add(new NumericqAction(model));
        Action.add(new OpenEndedqAction(model));
        Action.add(new RegisterAction(model));
        Action.add(new ResearcherAction(model));
        Action.add(new RespondentAction(model));
        Action.add(new SendSurveyAction(model));
        Action.add(new SocioCognitiveqAction(model));
        Action.add(new SurveySummaryAction(model));
        Action.add(new SurveyTitleAction(model));
        Action.add(new ViewSurveyAction(model));
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	doGet(request,response);
    }
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	 String nextPage;
    	  
		try {
			nextPage = performTheAction(request);
			sendToNextPage(nextPage,request,response);
		} catch (FormBeanException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    /*
     * Extracts the requested action and (depending on whether the user is logged in)
     * perform it (or make the user login).
     * @param request
     * @return the next page (the view)
     */
    private String performTheAction(HttpServletRequest request) throws FormBeanException {
        HttpSession session     = request.getSession(true);
        String      servletPath = request.getServletPath();
        String      action = getActionName(servletPath);
        User user = (User) session.getAttribute("user");
		
        String res_id = request.getParameter("q");
        
		// identify if it is from respondents' clicks
		if(res_id!=null && user==null){
			return Action.perform("login.do", request);
		}
		// Make the help page
		if(user==null && action.equals("help")){
			System.out.println("the action : " + action);
			return Action.perform("help.jsp", request);
		}
        	
		// Make the user log in first
		if (user == null || action.equals("start")) {
			return Action.perform("login.do", request);
		}
		// Make the researcher
		if (user.getType() == UserType.RESEARCHER && action.equals("start")) {
			return Action.perform("researcher.jsp", request);
		}
		
				
		
		// Let the logged-in user run his chosen action
		return Action.perform(action,request);
	}
	/*
     * If nextPage is null, send back 404
     * If nextPage starts with a '/', redirect to this page.
     *    In this case, the page must be the whole servlet path including the webapp name
     * Otherwise dispatch to the page (the view)
     *    This is the common case
     * Note: If nextPage 		equals "image", we will dispatch to /image.  In the web.xml file, "/image"
     *    is mapped to the ImageServlet will which return the image bytes for display.
     */
    private void sendToNextPage(String nextPage, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    	if (nextPage == null) {
    		response.sendError(HttpServletResponse.SC_NOT_FOUND,request.getServletPath());
    		return;
    	}
    	/*
    	 * if the user click a link, then redirect it to the corresponding website.
    	 */
    	//System.out.println("the next page is " + nextPage);
    	
    	// Downloading dynetml file requires special response content type
    	if (nextPage.endsWith("downloaddynetml")) {
	    	response.setContentType("application/octet-stream");
	    	response.setHeader("Content-Disposition", "attachment;filename=output.xml");
	    	
	    	HttpSession session = request.getSession();
	    	StringBuffer sb = (StringBuffer) session.getAttribute("dynetml");
	    	InputStream in = new ByteArrayInputStream(sb.toString().getBytes("UTF-8"));
	    	ServletOutputStream out = response.getOutputStream();
	    	
	    	int read = 0;
	    	byte[] outputByte = new byte[4096];
	    	while ((read = in.read(outputByte)) != -1) {
	    		out.write(outputByte, 0, read);
	    	}
	    	in.close();
	    	out.flush();
	    	out.close();
	    	session.setAttribute("dynetml", null);
    	}
    	else {
	    	if (nextPage.substring(0, 3).equals("url")){
	    		if(nextPage.substring(3,7).equals("http")){
	        		response.sendRedirect(nextPage.substring(3));
	        		return;
	    		}
	    		response.sendRedirect("http://" +  nextPage.substring(3));
	    		return;
	    	}
	    	if (nextPage.charAt(0) == '/') {
	    		String proto = request.isSecure() ? "https://" : "http://";
	    		String host  = request.getServerName();
				String port  = ":"+String.valueOf(request.getServerPort());
				if (port.equals(":80")) port = "";
				if (port.equals(":443")) port = "";
				String context = request.getContextPath();
				int lastSlash = context.lastIndexOf('/');
				String prefix = ( lastSlash==0 ? context : context.substring(0,lastSlash) );
				response.sendRedirect(proto+host+port+prefix+nextPage);
				return;
	    	}
	   		RequestDispatcher d = request.getRequestDispatcher("/jsp/"+nextPage);
	   		d.forward(request,response);
    	}
    }

	/*
	 * Returns the path component after the last slash removing any "extension"
	 * if present.
	 */
    private String getActionName(String path) {
    	// We're guaranteed that the path will start with a slash
        int slash = path.lastIndexOf('/');
        return path.substring(slash+1);
    }
}
